要分析 u-boot 的啟動流程 , 我們首先要找到 entry
, 找到第一行程式在哪裡。 程式的連結是由這個腳本所決定的 , 所以我們可以直接透過 [u-boot.lds](http://u-boot.lds)
找到程式的入口處。
如果還沒有編譯過 u-boot , 檔案應該會在 arch/arm/cpu/u-boot.lds
。 但這個並不是我們要用的 , 要用的會透過這個腳本經過編譯後生成 , 就在 uboot 這個跟目錄的底下 (u-boot/u-boot.lds)。
一定要經過編譯後才會生成。
編譯後的 u-boot.lds
打開來看會看到他的代碼,
可以將 configs 中我們要的 deconfig 檔案複製到 uboot 目錄下 , 並改名為 .config
, 之後可以運行
make make olddefconfig #這個指令會去更新舊有的config變成我們要的
make
編譯完成後就會出現 u-boot.lds檔案 , 點開來可以看到前面幾行會有
ENTRY(_start) # 這個就是入口點
這個 _start
位於 /home/yunen/u-boot/arch/arm/lib/vectors.S
, 如下圖
從上圖的這個文件中可以看到 _start 之後就是中斷向量表 , 並且可以從 .section “.vectors” , “ax”
得到 , 這段程式儲存在 .vectors 段中
.section 指令用於將組合語言代碼中的程式碼段或資料段放置到特定的段(section)中。
.section ".vectors", "ax" 指令具有以下含義和效果:
.section 指令:
.section 指令用於指定組合語言代碼中的段(section)。段是內存中一段連續的區域,通常用於組織和管理不同類型的資料或程式碼。
".vectors" 參數:
".vectors" 是段的名稱或識別符。在這裡,.vectors 可能指示一個特定的段,用於存放中斷向量表(Interrupt Vector Table)或其他在處理器引導時需要訪問的特定程式碼或資料。
"ax" 參數:
"ax" 是段的屬性標誌,指示了段的類型和屬性:
a 表示程式碼(allocatable),即該段可以被分配到內存中。
x 表示該段是可執行的,即該段中包含的程式碼可以被執行。
這些屬性標誌可以根據需要進行調整,以確保段中的內容能夠被正確地加載和執行。
透過下面指令可以查到 __image_copy_start 位置
grep -nR "__image_copt_start" #會顯示出 0x0000008787870000 __image_copy_start 之類的
接著我可以看到 u-boot.map 這個檔案 (編譯正常的話會產撐到根目錄或是輸出的地方) , 這個檔案是u-boot 的映射文件 , 我們可以從這當中看到某個文件 or 函數 連結到了哪個地址。
變數名稱 | 數值 (每個板子不同) | 說明 |
---|---|---|
__image_copy_start | 0x878000 | uboot 複製的起始位置 |
__image_copy_end | 0x8785dd54 | uboot 複製的結束位置 |
__rel_dyn_start | 0x8785dd54 | .rel.dyn 段 起始位置 |
__rel_dyn_end | 0x878668f4 | .rel.dyn 段 結束位置 |
_image_bimary_end | 0x878668f4 | 鏡像結束地址 |
__bss_start | 0x8785dd54 | .bss段起始地址 |
_bss _emd | 0x878a8e74 | .bss段結束地址 |
這些變數值(地址)都可以在 u-boot.map 文件當中找到 , 除了
__image_copy_start
以外 , 其他地址在每次編譯都有可能變化
通常不會從 0 開始將 uboot 官網的 uboot 移植到我們的開發平台上 , 半導體廠商會將 uboot 移植到原廠的板子上後測試沒問題並發出來,這就是 原廠的 BSP包。
我們會在基於原廠的 BSP包做修改 , 將uboot 與 kernel 移植到自家的板子上,大體上啟動流程如下 :
在 configs 底下有許多的 deconfig 檔案 , 以晶片來命名,有些會看到 9x9 14x14 等等的命名方式,則是使用晶片得尺寸 我們要選擇對應的來做配置。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- stm32mp25_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
指令一:make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- stm32mp25_defconfig
arm-linux-gnueabihf-gcc
作為編譯器。交叉編譯是為了在一種架構上編譯運行於另一種架構的程式碼,例如在 x86 架構的系統上編譯 ARM 架構的程式碼。_defconfig
表示使用預設的配置來設置編譯選項,通常是在開發新的嵌入式系統時使用的。總結來說,這條指令的作用是使用指定的 ARM 架構交叉編譯工具,並根據 stm32mp25
的預設配置文件準備好編譯環境。
指令二:make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
V=1
或 VERBOSE=1
會顯示更多的詳細編譯資訊,包括編譯命令和相關的輸出。這對於調試編譯問題很有用。j16
意味著同時執行 16 個編譯工作,這樣可以加速編譯過程,特別是在多核處理器系統上。總結來說,這條指令會以較詳細的方式顯示編譯過程的詳細資訊,同時利用多核心處理器的能力來加快編譯速度,同時使用指定的 ARM 架構交叉編譯工具鍊來進行編譯工作。
透過軟體(imxdownload)將uboot.bin檔案燒錄到 SD卡當中,命令如下
chmod 777 imxdownload # 給軟體權限
./imxdownload u-boot.bin /dev/sdd # 燒寫SD卡 千萬不可以燒錄到 /dev/sda or sda1當中
燒錄完成後可以將SD卡插入開發板的TF卡槽當中 , 設定開發板以 SD卡啟動 。 打開串口調適助手並且reset開發板後就可以接收到訊息了。
mmc list #列出當前的mmc設備
mmc dev 0 #檢查 mmc 設備0
mmc info
### 可以看看容量是多少去比對看看是哪個設備 假如是14G多 可能就是我們的 16G SD卡
mmc dev 1 # 同上
mmc info # 可能是 emmc